package com.hsource.usercenter.controller;

import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.aliyun.oss.OSSClient;
import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.hsource.common.utils.CommonAuth;
import com.hsource.common.utils.CommonResp;
import com.hsource.common.utils.DateUtil;
import com.hsource.common.utils.JwtUtil;
import com.hsource.usercenter.config.dataSource.aspect.SnowflakeIdWorker;
import com.hsource.usercenter.domain.UserBase;
import com.hsource.usercenter.feign.CyUserLoginFeignClient;
import com.hsource.usercenter.service.IUserBaseService;
import com.hsource.usercenter.util.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Author itoug
 * @Crreate 2020-10-16 16:08
 */
@Slf4j
@RestController
@RequestMapping("/hsource-user")
@Api(tags = "用户中心")
@RefreshScope
public class UserController {

    @Value(value = "${YZ_LOGIN_URL_1:000000}")
    private String YZ_LOGIN_URL_1;

    @Value(value = "${YZ_LOGIN_URL:https://account.youzan.com/api/login/native/open/login-or-register.json}")
    private String YZ_LOGIN_URL;

    @Value(value = "${YZ_USER_IMPORT:https://open.youzanyun.com/api/youzan.user.platform.import/1.0.0}")
    private String YZ_USER_IMPORT;

    @Value(value = "${YZ_ACCESS_TOKEN:https://open.youzanyun.com/auth/token}")
    private String YZ_ACCESS_TOKEN;

    @Value(value = "${CLIENT_ID:3406c7f6b77c60feb8}")
    private String CLIENT_ID;

    @Value(value = "${OPEN_USER_ID:90945959}")
    private String OPEN_USER_ID;

    @Value(value = "${accessKeyId:LTAI4GEde7uxNWsZzS54ybPJ}")
    private String accessKeyId;

    @Value(value = "${accessSecret:WOYNauq0j6yD1lxmqgeClYhnflSLus}")
    private String accessSecret;

    @Value(value = "${RegionId:cn-hangzhou}")
    private String RegionId;

    @Value(value = "${SignName:本草元堂}")
    private String SignName;

    @Value(value = "${TemplateCode:SMS_201730025}")
    private String TemplateCode;

    @Value(value = "${JsonPath:/usr/local/data/index.json}")
    private String JsonPath;

    @Value(value = "${Index_Redis_Key:index}")
    private String Index_Redis_Key;

    private static final String smsPrefix = "sms-";

    private static final String userPrefix = "user-";

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private IUserBaseService userBaseService;

    @Autowired
    private OSSUtil ossUtil;

    /**
     * 更新用户信息
     * @param userBase
     * @return
     */
    @PostMapping(value = "/updateUser")
    @ResponseBody
    public Object updateUser(UserBase userBase,HttpServletRequest request){
        CommonResp commonResp = new CommonResp();
        userBase.setLastLoginTime(Calendar.getInstance().getTime());
        userBase.setLastIp(IpAdressTool.getIpAddr(request));
        userBase.setUpdateTime(Calendar.getInstance().getTime());
        int i = userBaseService.updateUserBase(userBase);
        if(i>0) {
            return commonResp.success();
        }
        return commonResp.failed();
    }

    /**
     * 获取用户信息
     * @param id
     * @return
     * @throws Exception
     */
    @PostMapping(value = "/userInfo")
    @ResponseBody
    public Object userInfo(@RequestBody String id) throws Exception {
        CommonResp commonResp = new CommonResp();
        UserBase userBases = userBaseService.selectUserBaseById(id);
        if(userBases!=null){
            Map<String,Object> map=new HashMap<>();
            if(userBases.getBirthday()!=null&&!"".equals(userBases.getBirthday())) {
                userBases.setAge(DateUtil.getAge(DateUtil.getDateFromStr(userBases.getBirthday() + " 00:00:00", "")));
            }
            map.put("userInfo",userBases);
            return commonResp.success(map);
        }
        return commonResp.failed("未查询到用户信息");

    }

    /**
     * 获取用户信息
     * @param request
     * @return
     * @throws Exception
     */
    @PostMapping(value = "/getUserInfo")
    @ResponseBody
    public Object getUser(HttpServletRequest request) throws Exception {
        CommonResp commonResp = new CommonResp();
        String id = request.getParameter("userId");
        UserBase userBases = userBaseService.selectUserBaseById(id);
        if(userBases!=null){
            Map<String,Object> map=new HashMap<>();
            if(userBases.getBirthday()!=null&&!"".equals(userBases.getBirthday())) {
                userBases.setAge(DateUtil.getAge(DateUtil.getDateFromStr(userBases.getBirthday() + " 00:00:00", "")));
            }
            map.put("userInfo",userBases);
            return commonResp.success(map);
        }
        return commonResp.failed("未查询到用户信息");

    }


    public String getHaderImageUrl(MultipartHttpServletRequest request){
        //开始上传
        MultiValueMap<String, MultipartFile> multiFileMap = request.getMultiFileMap();
        List<MultipartFile> files = new ArrayList<>();
        for (Map.Entry<String, List<MultipartFile>> temp : multiFileMap.entrySet()) {
            files.addAll(temp.getValue());
        }
        OSSClient client = ossUtil.getOSSClient();

        if(files.stream().count()>0){
            MultipartFile file = files.get(0);
            String fileName = file.getOriginalFilename();
            int len = fileName.lastIndexOf(".");
            String fileType1 = fileName.substring(len + 1).toLowerCase();
            String md5key = ossUtil.uploadObject2OSS(client, file);
            return md5key;
        }
        return null;
    }

    @PostMapping(value = "/login")
    @ResponseBody
    @ApiOperation(value = "模拟登录", notes = "模拟登录")
    public Object login(String phone, String smscode, String deviceBrand, String deviceModel, String deviceNumber
            , String flag, String geo_latitude, String geo_longitude) {
        CommonAuth commonAuth = new CommonAuth();
        CommonResp commonResp = new CommonResp();
        /*System.out.println("phone="+vo.getPhone()
                +",smscode="+vo.getSmscocde()
                +",devicebrand="+vo.getDevicebrand()
                +",devicemodel="+vo.getDevicemodel()
                +",devicenumber="+vo.getDevicenumber()
                +",flag="+vo.getFlag()
                +",geo_latitude="+vo.getGeo_latitude()
                +",geo_longitude="+vo.getGeo_longitude());*/

        if (StringUtils.isEmpty(phone)) {
            return commonResp.failed("手机号为空！");
        }

        if (StringUtils.isEmpty(smscode)) {
            return commonResp.failed("验证码不能为空！");
        }

        String key = smsPrefix + phone;
        String value = redisUtil.get(key).toString();

        if (StringUtils.isEmpty(value)) {
            return commonResp.failed("验证码已失效，请重新发送验证码！");
        }

        if (!value.equals(smscode)) {
            return commonResp.failed("验证码错误，请重新输入！");
        }

        String redisUser = redisUtil.get(userPrefix+phone).toString();
        UserBase userBase = JSON.parseObject(redisUser,UserBase.class);

        String uid = "A800130";
        if(userBase!=null){
            uid = userBase.getId();
            UserBase ub=new UserBase();
            ub.setId(uid);
            ub.setLastLoginTime(Calendar.getInstance().getTime());
            ub.setLastIp(IpAdressTool.getIpAddr(ServletUtils.getRequest()));
            ub.setDeviceBrand(deviceBrand);
            ub.setDeviceModel(deviceModel);
            ub.setDeviceNumber(deviceNumber);
            userBaseService.updateUserBase(ub);
        }else{
            return new CommonResp().failed("查询用户失败！");
        }

        HashMap<String, Object> paramMap = new HashMap<>();
        paramMap.put("client_id", CLIENT_ID);
        paramMap.put("open_user_id", uid);

        String result = HttpUtil.post(YZ_LOGIN_URL, paramMap);

        if (StringUtils.isEmpty(result)) {
            return new CommonResp().failed();
        } else {
            JSONObject jsonObject = JSONUtil.parseObj(result);
            JSONObject jsonData = jsonObject.getJSONObject("data");


            if (jsonData != null) {
                commonAuth.setCookie_key(jsonData.get("cookie_key").toString());
                commonAuth.setCookie_value(jsonData.get("cookie_value").toString());

                Long second = LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8"));


                String userJson = "{\"uid\":\""+uid+"\",\"tms\":\"" + second + "\"}";
                String token = JwtUtil.createJWT(userJson);
                commonAuth.setToken(token);
            }
            commonResp.setAuth(commonAuth);
            return commonResp.success();
        }

    }

    @PostMapping(value = "/sendsms")
    @ResponseBody
    @ApiOperation(value = "发送验证码", notes = "发送验证码")
    public Object SendSms(String phone) {

        String regex = "^1[3|4|5|6|7|8|9][0-9]{9}$";
        if (phone.length() != 11) {
            return new CommonResp().failed("手机号应该为11位！");
        } else {
            Pattern p = Pattern.compile(regex);
            Matcher m = p.matcher(phone);
            boolean isMatch = m.matches();
            if (!isMatch) {
                return new CommonResp().failed("手机号格式不正确");
            }
        }

        DefaultProfile profile = DefaultProfile.getProfile(RegionId, accessKeyId, accessSecret);
        IAcsClient client = new DefaultAcsClient(profile);

        CommonRequest request = new CommonRequest();
        request.setSysMethod(MethodType.POST);
        request.setSysDomain("dysmsapi.aliyuncs.com");
        request.setSysVersion("2017-05-25");
        request.setSysAction("SendSms");
        request.putQueryParameter("RegionId", RegionId);
        request.putQueryParameter("PhoneNumbers", phone);
        request.putQueryParameter("SignName", SignName);
        request.putQueryParameter("TemplateCode", TemplateCode);
        String verifyCode = String.valueOf((int) (Math.random() * 9000 + 1000));

        request.putQueryParameter("TemplateParam", "{'code':'" + verifyCode + "'}");


        try {
            CommonResponse response = client.getCommonResponse(request);
            String smsKey = smsPrefix + phone;
            redisUtil.set(smsKey, verifyCode);
            //有效时间5分钟
            redisUtil.expire(smsKey, 1000 * 5);
            System.out.println(response.getData());


            UserBase userBase = new UserBase();
            userBase.setPhone(phone);

            List<UserBase> userBaseList = userBaseService.selectUserBaseList(userBase);
            // 验证码发送成功，查看用户是否注册
            // 没注册，需要注册，并且还需要同步到春雨医生，也需要同步到有赞
            // 已注册，不做事
            if (userBaseList == null || userBaseList.size() == 0) {
                SnowflakeIdWorker idWorker = new SnowflakeIdWorker(1, 1);
                String id = String.valueOf(idWorker.nextId());
                userBase.setName(phone);
                userBase.setId(id);
                userBase.setCreateTime(new Date());

                String userRedisJson = JSON.toJSONString(userBase);
                redisUtil.set(userPrefix+phone,userRedisJson);
                if (0 == userBaseService.insertUserBase(userBase)) {
                    return new CommonResp().failed("用户注册失败！");
                }
                //同步到春雨
                CyUserLoginFeignClient cyUserLoginFeignClient = SpringUtils.getBean(CyUserLoginFeignClient.class);

                CommonResp commonResp = cyUserLoginFeignClient.cyUserLogin(id, "123456");

                if (!commonResp.getSuccess()) {
                    return commonResp;
                }

                //同步到有赞
                //1.先查询acess_token

                com.alibaba.fastjson.JSONObject yzyJsonObject = userBaseService.getYZYJsonObject();
                if(yzyJsonObject!=null){
                    String access_token = yzyJsonObject.getString("access_token");
                    Map<String,String> map=new HashMap<>();
                    map.put("country_code","+86");
                    map.put("mobile",phone);
                    map.put("open_user_id",id);
                    String post = HttpUtil.post("https://open.youzanyun.com/api/youzan.user.platform.import/1.0.0?access_token=" + access_token, com.alibaba.fastjson.JSONObject.toJSONString(map));
                    com.alibaba.fastjson.JSONObject jsonObject = com.alibaba.fastjson.JSONObject.parseObject(post);
                    if(jsonObject.getInteger("code")!=200){
                        return commonResp.failed(jsonObject.getString("message"));
                    }
                }
                //2.user导入有赞

            }

        } catch (com.aliyuncs.exceptions.ClientException e) {
            e.printStackTrace();
            return new CommonResp().failed("发送验证码失败！");
        }
        return new CommonResp().success();
    }

    @PostMapping(value = "/nacos")
    @ResponseBody
    @ApiOperation(value = "Nacos动态配置")
    public String testNacosConfig(String ip, String userId) {
        return YZ_LOGIN_URL_1 + ",userId=" + userId + ",ip=" + ip;
    }

    @PostMapping(value = "/index")
    @ResponseBody
    @ApiOperation(value = "首页")
    public Object index() {


        boolean indexInRedis = redisUtil.hasKey(Index_Redis_Key);

        if (!indexInRedis) {
            String jsonStr = null;
            try {
                jsonStr = FileUtils.readFileToString(new File(JsonPath), "utf-8");
            } catch (IOException e) {
                e.printStackTrace();
            }

            if (jsonStr != null) {
                com.alibaba.fastjson.JSONObject json = JSON.parseObject(jsonStr);
                redisUtil.set("index", json);
                return new CommonResp().success(json);
            } else {
                return new CommonResp().failed();
            }
        } else {
            return new CommonResp().success(redisUtil.get(Index_Redis_Key));
        }
    }
}
